package uploader

import (
	"container/list"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/url"
	"os"
	"strconv"
	"strings"
	"time"

	"github.com/aliyun/aliyun-oss-go-sdk/oss"
)

type AliOssUploader struct {
	EndPoint        string
	AccessKeyId     string
	AccessKeySecret string
	Bucket          string
	PathPrefix      string
	Area            string
	BucketObj       *oss.Bucket
}

func (aliOssUploader *AliOssUploader) DoUpload(filePath []string) {
	fmt.Println("需要上传的文件路径", filePath)
	client := ConnectUploadServer()
	now := time.Now()
	dateStr := fmt.Sprintf("%04d%02d", now.Year(), now.Month())

	au := BaseObjectUploaderMap["alioss"].(*AliOssUploader)
	// 获取存储空间
	bucket, err := client.Bucket(au.Bucket)
	if err != nil {
		fmt.Println("获取存储空间失败:", err)
		os.Exit(-1)
	}
	au.BucketObj = bucket
	au.PathPrefix += dateStr + "/"

	uploadFileName := ""
	uploadSuccessList := list.New()
	for _, path := range filePath {
		f, err2 := os.Stat(path)
		if err2 != nil {
			fmt.Println("本地文件查看失败:", path, err)
			continue
		}
		uploadFileName = f.Name()

		// 判断是否有同名文件，有则处理
		isExist, err := bucket.IsObjectExist(au.PathPrefix + uploadFileName)
		if err != nil {
			fmt.Println("判断文件失败:", err)
			continue
		}
		fmt.Println("path Exist:", isExist)
		if isExist {
			strArr := strings.Split(uploadFileName, ".")
			strArr[0] = GenerateRepeatFileName(au, strArr[0])
			uploadFileName = strings.Join(strArr, ".")
		}

		err = bucket.PutObjectFromFile(au.PathPrefix+uploadFileName, path)
		if err != nil {
			fmt.Println("文件上传失败:", path, err)
			continue
		}

		uploadSuccessList.PushBack("https://" + au.Bucket + "." + au.EndPoint + "/" + au.PathPrefix + url.QueryEscape(uploadFileName))
	}

	fmt.Println("Upload Success:")
	for i := uploadSuccessList.Front(); i != nil; i = i.Next() {
		fmt.Println(i.Value)
	}
}

func ParseSetting(path string) (map[string]interface{}, error) {
	inputFile, inputError := os.Open(path)
	if inputError != nil {
		fmt.Println("打开配置文件出错，请检查")
		return nil, inputError
	}

	settingByte, _ := ioutil.ReadAll(inputFile)
	var result map[string]interface{}
	json.Unmarshal(settingByte, &result)

	defer inputFile.Close()

	return result, nil
}

func ConnectUploadServer() *oss.Client {
	objectUploader := BaseObjectUploaderMap["alioss"].(*AliOssUploader)

	client, err := oss.New(
		"http://"+objectUploader.EndPoint,
		objectUploader.AccessKeyId,
		objectUploader.AccessKeySecret)
	if err != nil {
		fmt.Println("初始化错误:", err)
		os.Exit(-1)
	}

	return client
}

// 为重复文件生成数字后缀
// au 阿里云oss相关对象和信息
// uploadFileName 文件名（无后缀）
func GenerateRepeatFileName(au *AliOssUploader, uploadFileName string) string {
	bucket := au.BucketObj
	lsRes, err := bucket.ListObjects(oss.Prefix(au.PathPrefix + uploadFileName))
	if err != nil {
		fmt.Println("Error:", err)
		os.Exit(-1)
	}

	sArr := strings.Split(lsRes.Objects[len(lsRes.Objects)-1].Key, "/")
	fName := sArr[len(sArr)-1]
	fmt.Println("oss存在的文件名为:", fName)

	fFullNameStrArr := strings.Split(fName, ".")
	fNameStrArr := strings.Split(fFullNameStrArr[0], "_")
	if len(fNameStrArr) == 1 {
		fName = fNameStrArr[0] + "_00"
	} else {
		i, err2 := strconv.Atoi(fNameStrArr[1])
		if err2 != nil {
			fmt.Println("strconv.Atoi出错", err2)
		}

		fName = fmt.Sprintf(fNameStrArr[0]+"_%02d", i+1)
	}

	fmt.Println("结果文件名为:", fName)
	return fName
}
